home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 4 / CU Amiga Magazine's Super CD-ROM 04 (1996)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1996-11].iso / magazine / psion / new / opp16f.lzx / manual1.txt next >
Text File  |  1996-09-20  |  37KB  |  926 lines

  1.                                                               
  2.                      Psion 3a OPL Preprocessor
  3.                                  
  4.                              OPP V1.6
  5.                                  
  6.                             User Guide
  7.                                  
  8.                    Copyright Andy Clarkson 1995
  9.  
  10. CONTENTS
  11.  
  12. 1. INTRODUCTION
  13.     An introduction to OPP, describing what it does.
  14.  
  15. 2. INSTALLATION
  16.     Instructions on installing OPP.
  17.  
  18. 3. USING OPP
  19.     This section describes how to use OPP.
  20.  
  21. 4. SHAREWARE REGISTRATION
  22.     How to register OPP.
  23.  
  24. 5. KEY FEATURES
  25.     A bulleted list of all OPP's features.
  26.  
  27. 6. MACROS
  28.     How to create and use OPP preprocessor macros using #define.
  29.  
  30. 7. CONDITIONS
  31.     How to control which sections of OPP code are translated using #if,
  32.     #ifdef, #ifndef, #elif, #else and #endif.
  33.  
  34. 8. INCLUDE FILES
  35.     How to use include files with OPP (#include)
  36.  
  37. 9. PRAGMAS
  38.     OPP special controls, such as: checking for procedures called but not
  39.     defined and anti-Revtran measures.
  40.  
  41. 10. LANGUAGE EXTENSIONS
  42.     OPL language extensions supported by OPP such as: multi-dimensional
  43.     arrays, C style structures and operators.
  44.  
  45. 11. HISTORY
  46.     Summary of changes made to OPP since version 1.0.
  47.  
  48.  
  49. 1. INTRODUCTION
  50.  
  51. OPP is an OPL pre-processor for the Psion OPL language. If you are
  52. familiar with the operation of a C pre-processor then the function of
  53. OPP will be immediately clear. S3ATRAN provides similar facilities
  54. when translating OPL code on a PC. OPP provides the same facilities
  55. as S3ATRAN plus a large number of additional features. These
  56. additional features provide extensions to the OPL language, such as
  57. support for multi-dimensional arrays and C style structures. Also,
  58. whereas S3ATRAN only runs on a PC, there are both PC and Psion
  59. versions of OPP.
  60.  
  61. When using a pre-processor additional pre-processor commands are
  62. added in-line to the source file. These commands are read and
  63. executed by the pre-processor which strips the lines out prior to the
  64. actual compilation or translation of the source file. OPP looks for
  65. lines within the OPL source file which begin with a # character.
  66. These lines contain commands which are read and acted upon by the pre-
  67. processor. Any # lines are removed prior to dispatching the lines to
  68. the OPL translator. The standard OPL code is also scanned by the pre-
  69. processor which may substitute symbolic names for text defined using
  70. the # commands. The output from OPP is pure OPL source code. This
  71. resultant pre-processed OPL code is passed on to the OPL translator
  72. which does the actual job of creating an OPO or OPA file.
  73.  
  74. The operation of the pre-processor can be seen with an example. In
  75. the Program editor the following code is written:
  76.  
  77.         #define ARRAY_SIZE     10
  78.         #define FN(x)          (3*x**2+2*x+1)
  79.         /* Here is the main procedure */
  80.         PROC main:
  81.                 local x%, y%(ARRAY_SIZE)
  82.                 #ifdef DEBUG      /* print debug info if required */
  83.                         print "In main"
  84.                 #endif
  85.                 while x%<ARRAY_SIZE
  86.                         x%=x%+1
  87.                         y%(x%)=FN(x%)
  88.                 endwh
  89.                 foo:
  90.         ENDP
  91.         #include "foo.oph"
  92.         
  93. The OPL pre-processor reads in the above code and outputs the
  94. following code to the OPL translator:
  95.  
  96.         PROC main:
  97.                 local x%, y%(10)
  98.                 while x%<10
  99.                         x%=x%+1
  100.                         y%(x%)=(3*x%**2+2*x%+1)
  101.                 endwh
  102.                 foo:
  103.         ENDP
  104.         (the rest of the foo.oph file appears here...)
  105.         
  106. The OPL translator then reads in the above code and outputs the
  107. appropriate OPO or OPA file.
  108.  
  109. As can be seen from the above example the main purpose of a pre-
  110. processor is to enable source code to be written which is easier to
  111. read and maintain.
  112.  
  113. 2. INSTALLATION
  114.  
  115. This section describes how to install the Psion and MSDOS versions of
  116. OPP.
  117.  
  118. Psion OPP
  119. ---------
  120. The Psion version of OPP has been tested on the Psion Series 3a, it
  121. should also work on other Psion computers such as the Series 3c, Siena,
  122. Series 3, Workabout and HC. If you try it on one of these then let
  123. me know that it works OK.
  124.  
  125. To install OPP onto a Psion copy the files OPP.ALS and OPH.ALS to the
  126. directory \APP on any drive. Also copy the file SYS$PRGP.IMG to the
  127. directory \IMG on any drive, e.g.:
  128.  
  129.         M:\IMG\SYS$PRGP.IMG           (required)
  130.         M:\APP\OPP.ALS                (required)
  131.         M:\APP\OPH.ALS                (optional)
  132.         
  133. There are a number of other useful files that may also optionally be
  134. installed. These are the system include files supplied in the INCLUDE
  135. directory. These files have an extension OPH and should be installed
  136. into the directory \OPP\INCLUDE on any drive. Refer to the section on
  137. include files for further details.
  138.  
  139. Install OPP.ALS and OPH.ALS using the Apps->Install menu option on
  140. the main Psion System Screen. This will add the OPP and OPH Program
  141. editor icons to the system screen. These icons are similar to the
  142. standard OPL Program icon but have a trailing letter P and H instead
  143. of L on the icon. The OPP and OPH editors are aliases of the OPL
  144. Program editor. When writing OPP code which includes preprocessor
  145. directives use the OPP or OPH editor rather than the standard OPL
  146. editor. They operate in exactly the same way as the OPL Program
  147. application, with two main exceptions...
  148.  
  149. Firstly the files which are displayed beneath the icon have a
  150. different extension. To distinguish between OPL source files
  151. containing preprocessor directives from plain OPL files the following
  152. directory and file extensions are recommended:
  153.  
  154.         Normal OPL files               \OPL\             .OPL
  155.         OPL containing OPP directives  \OPP\             .OPP
  156.         OPP include files              \OPP\             .OPH
  157.         OPP system include files       \OPP\INCLUDE\     .OPH
  158.         
  159. Files with an OPP extension in the OPP directory will appear beneath
  160. the OPP editor. Files with an OPH extension in the OPP directory will
  161. be listed beneath the OPH editor.
  162.  
  163. The second main difference between the OPP and OPH editors and the
  164. OPL editor is that they run the OPL preprocessor rather than the OPL
  165. translator when translating, running and debugging OPP code.
  166.  
  167. Once OPP has been installed, exactly the same OPL programming
  168. environment is available, i.e. OPP source code may be written,
  169. translated and run via an editor. When the translate menu option is
  170. selected from the OPP editor instead of activating the OPL translator
  171. directly this activates the OPL preprocessor. The preprocessor in
  172. turn starts up the OPL translator under its control. The preprocessor
  173. reads OPP code directly from the editor a line at a time, pre-
  174. processes each line and passes it to the OPL translator.
  175.  
  176. Note that the OPL outliner is not available within the OPP and OPH
  177. editors due to the way Psion alias files work. It will probably not
  178. be possible to provide this facility since the required changes would
  179. need to be made to the software built into the ROM of the Psion.
  180.  
  181. OPP requires a minimum of 26K of disk space for installation, much
  182. more if the include files are also installed. When translating an OPP
  183. file additional run-time memory is required by the preprocessor. The
  184. amount of run-time memory used by the preprocessor is proportional to
  185. the number of macros and structures defined.
  186.  
  187. MSDOS OPP
  188. ---------
  189. The MSDOS version of OPP may be installed on a PC and used to create
  190. OPO/OPA files entirely on the PC. The OPO/OPA files may then be used
  191. via the PC based Psion emulator or transferred to a Psion.
  192.  
  193. MSDOS OPL translators and the Psion emulator
  194. --------------------------------------------
  195. To use the MSDOS version of OPP you will need to obtain an MSDOS
  196. based Psion OPL translator. The translator required depends upon the
  197. target Psion computer:
  198.  
  199.     Psion computer                      Translator
  200.     
  201.     Psion 3a                            S3ATRAN
  202.     Psion 3                             S3TRAN
  203.     Workabout                           WATRAN
  204.     HC                                  HCTRAN
  205.  
  206. If are using Psion's ODE development tool then it includes all the
  207. above translators, otherwise you will need to obtain the appropriate
  208. translator. The Series 3a translator, S3ATRAN, is freely available
  209. from CompuServe, CIX or the Psion archives on the Internet:
  210.  
  211.  ftp://sunsite.doc.ic.ac.uk/packages/psion/icdoc/development/s3atra.zip
  212.  ftp://ftp.frontiernet.net/pub/psion/devel/s3atran.zip
  213.  ftp://ftp.nwt.com/S3a/Developer/OPL/S3ATRAN.ZIP
  214.  
  215. The Series 3a emulator which emulates a Psion 3a on a PC is also
  216. freely available from:
  217.  
  218.  ftp://sunsite.doc.ic.ac.uk/packages/psion/icdoc/development/s3aem1.zip
  219.  ftp://ftp.frontiernet.net/pub/psion/devel/emulator.zip
  220.  ftp://ftp.nwt.com/S3a/Developer/Emulator/S3AEMUL.ZIP
  221.  http://www.psion.com/testzone/index.html
  222.  
  223. Using OPP with ODE
  224. ------------------
  225. OPP may be used with Psion's ODE development environment. ODE
  226. essentially provides an editor front-end to the back end OPL
  227. translator (S3ATRAN,...).
  228.  
  229. To use OPP with ODE the OPP.EXE file should be copied into the ODE
  230. directory (normally C:\ODE). Then you need to tell ODE about OPP.
  231. This is done by editing the file ODE.INI, which will be found in the
  232. windows directory (e.g. C:\WINDOWS). Edit this file and find the line
  233. at the top which starts...
  234.  
  235.        [Machines]
  236.  
  237. ...change this section to add an appropriate line for using OPP on the
  238. given machine, e.g.
  239.  
  240.        [Machines]
  241.        Comp0=Workabout
  242.        Comp1=HC
  243.        Comp2=Series3
  244.        Comp3=Series3A
  245.        Comp4=Series3A-OPP
  246.        
  247. Next find the current section for the target machine, e.g.
  248.  
  249.        [Series3A]
  250.        Tran=S3ATRAN
  251.        OplRun=rom::sys$prgo.img
  252.        OplLint=-tmcwa
  253.        TranDef=_SERIES3A
  254.        
  255. ...copy this section to a new section with the same name as in the
  256. [Machines] section, change the "Tran" item to refer to OPP and add
  257. " -dODE" to the TranDef item, e.g.
  258.  
  259.        [Series3A-OPP]
  260.        Tran=OPP
  261.        OplRun=rom::sys$prgo.img
  262.        OplLint=-tmcwa
  263.        TranDef=_SERIES3A -dODE
  264.        
  265. OPP relies upon the translator to do the back-end translation of OPL
  266. code and therefore OPP needs to be able to find S3ATRAN, S3TRAN,
  267. WATRAN or HCTRAN. OPP will look for the translator in a directory
  268. which is listed in the MSDOS PATH environment variable. When using
  269. ODE, the translators will be located in the ODE directory and
  270. therefore this directory should be added to the PATH. The best place
  271. to set this is in the AUTOEXEC.BAT file, e.g.
  272.  
  273.         set PATH=C:\ODE;%PATH%
  274.         
  275. When ODE is next started you can set the "Target" item on the project
  276. window to the appropriate value, e.g. "Series3A-OPP", to translate a
  277. project using OPP with the appropriate translator.
  278.  
  279. Note: By default OPP works with the Series 3a OPL translator,
  280. S3ATRAN, if you are using OPP with an alternative machine then refer
  281. to section 9.13 for details on how to ensure the correct translator
  282. is used.
  283.  
  284. Because OPP provides language extensions to standard OPL it is not
  285. possible to use the OPL lint utility which checks for errors in OPL
  286. code. For this reason, when using ODE, turn OPL lint checking off.
  287. This can be done by unchecking the items for lint under the menu
  288. options "Options->Build" and "Options->Run" in ODE.
  289.  
  290. When using OPP with ODE it is best to stick with the conventional
  291. file extensions used with OPL code, i.e. OPL rather than OPP.
  292. The supplied include files may also optionally be installed. These
  293. files have an extension OPH and should be installed into the
  294. directory C:\OPP\INCLUDE. The include files may be installed into an
  295. alternative directory if required. In this case select the "Options-
  296. >Translate" menu in ODE and set the include path to the alternative
  297. location. Refer to the section on include files for further details
  298. on what the include files provide.
  299.  
  300. Using OPP from an MSDOS prompt
  301. ------------------------------
  302. OPP.EXE should be installed onto the PC into a directory which is
  303. specified in the PATH environment variable (type "path" at an MSDOS
  304. prompt to check what the path is set to). If you are using OPP with
  305. ODE then adding the ODE directory to the PATH is the best solution,
  306. otherwise a convenient location is the Windows directory, usually
  307. C:\WINDOWS. The appropriate OPL translator (S3ATRAN, S3TRAN, WATRAN
  308. or HCTRAN) utility should also be accessible in the PATH.
  309.  
  310. Note: By default OPP works with the Series 3a OPL translator,
  311. S3ATRAN, if you are using OPP with an alternative machine then refer
  312. to section 9.13 for details on how to ensure the correct translator
  313. is used.
  314.  
  315. The supplied include files may also optionally be installed. These
  316. files have an extension OPH and should be installed into the
  317. directory C:\OPP\INCLUDE. If the include files are installed into
  318. another directory then the "-i" command line option should be used to
  319. specify this directory when using OPP. Refer to the section on
  320. include files for further details on what the include files provide.
  321.  
  322. 3. USING OPP
  323.  
  324. Psion OPP
  325. ---------
  326. Once OPP has been installed the menu options "Translate", "S3
  327. Translate" and "Run" may be used from the OPP program editor to
  328. translate and run OPP programs in exactly the same way as with the
  329. normal Program editor.
  330.  
  331. When translating an OPP program the OPP screen will appear. This
  332. screen will show the progress of the translation along with any error
  333. and warning messages. (The #pragma directive discussed in a later
  334. section may be used to control the display of additional information
  335. during translation).
  336.  
  337. If during translation the screen is switched to another Psion
  338. application then the shift-system key combination may be used to
  339. cycle through the active applications in order to get back to the OPP
  340. screen.
  341.  
  342. The escape key may be used to abort the translation at any point when
  343. the OPP screen is visible.
  344.  
  345. If any pre-processor errors are found during the pre-processing of
  346. the OPP code then control will return to the OPP editor. An error
  347. message will be displayed in the lower right corner and the cursor
  348. will be repositioned on the line where the error was detected.
  349.  
  350. If an OPL translator error is discovered during translation this will
  351. be displayed on the OPP screen along with the associated pre-
  352. processed OPL line. A ^ character will indicate the position on the
  353. line where the error was detected. To continue press any key. The
  354. cursor in the OPP editor will then be repositioned on the line where
  355. the error was found.
  356.  
  357. Note that with OPL errors the position of the cursor along the line
  358. may not necessarily indicate the exact character where the error was
  359. found. This is due to the fact that the cursor is placed on the
  360. relevant character in relation to the pre-processed line. If there
  361. are any macros before this point on the line the position may be
  362. incorrect.
  363.  
  364. Running an application from the OPP editor will also activate the OPL
  365. pre-processor. This in turn will then run the requested program. If a
  366. run-time error is encountered then control will return to the OPP
  367. editor. At this point, if the program being run was translated from
  368. the source in the program editor, then OPP will be restarted. This is
  369. in order to determine exactly where the error occurred within the
  370. source file. During this "error decoding" phase the pre-processor
  371. will scan the source code for the line where the error was
  372. encountered. This line will be displayed on the OPP screen and the
  373. cursor repositioned in the OPP editor. The escape key may be used
  374. during the error decoding phase to abort the process.
  375.  
  376. MSDOS OPP
  377. ---------
  378. Type OPP at an MSDOS prompt to display usage information for OPP. The
  379. command line syntax and output from OPP is identical to the Psion
  380. translators (S3ATRAN,.).
  381.  
  382. Differences between the MSDOS and Psion versions of OPP
  383. There are some differences between the MSDOS and Psion versions of
  384. OPP. These differences are as follows:
  385.  
  386.    -  There is a limit to the amount of code which the MSDOS based
  387.       OPL translators (S3ATRAN,.) can handle. This limit also applies when
  388.       using the MSDOS version of OPP. The Psion version of OPP does not
  389.       have a limit and can translate any amount of code.
  390.  
  391.    -  The MSDOS version of OPP can handle any number of OPP macros or
  392.       structure definitions. The Psion version is limited to 64K of memory
  393.       storage which will impose an upper limit on the number of #defines
  394.       and structures which can be declared.
  395.       
  396.    -  Some of the pre-defined macros which are present in the Psion
  397.       3a version are not applicable in the MSDOS version:
  398.       
  399.            OsVersion
  400.            RomVersion
  401.            PsuType
  402.            LcdType
  403.            
  404.    -  When using the MSDOS version of OPP with ODE some of the
  405.       #pragma options are not available. Any option which causes OPP to stop
  406.       and wait for a key press is disabled when using OPP with ODE since
  407.       OPP is run behind the scenes with no user input possible (see section
  408.       9 for the list of #pragma's).
  409.  
  410.    -  The MSDOS version of OPP uses different software for the evaluation
  411.       of expressions at translate time (as opposed to runtime).
  412.       Expressions are evaluated at translate time when the OPPEVAL() macro
  413.       is used (see later) and also in the #if directive. The MSDOS version
  414.       of OPP does not support all the functions available in the Psion 3a
  415.       version at translate time (note that you can still use these
  416.       functions at run-time, i.e. in normal code), in particular the
  417.       following are not supported in OPPEVAL() and #if:
  418.       
  419.            YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEK,
  420.            DATETOSECS(), DAYS(), DOW(),
  421.            PI, RND,
  422.            MAX(), MIN(), MEAN(), STD(), VAR(), SUM(),
  423.            UADD(), USUB()
  424.  
  425. 4. SHAREWARE REGISTRATION
  426.  
  427. OPP is shareware, which means that if you continue to use it you
  428. should register with the author. To encourage registration the Psion
  429. version of the pre-processor will pause for 30 seconds at the end of
  430. every translation until it is registered. The MSDOS version will not
  431. pause, but will display a warning message. To register OPP send a 10
  432. UK pounds cheque to:
  433.  
  434.         Mr. A. Clarkson,
  435.         3 Ashmead Drive,
  436.         Hardwick,
  437.         Cambridgeshire.
  438.         CB3 7XT.
  439.         U.K.
  440.         
  441. State the version of the program, which is 1.6F, and where you
  442. obtained the copy. This will enable me to check that you are using
  443. the latest version.
  444.  
  445. When you register you will receive instructions on how to remove the
  446. time delay or warning message at the end of a translation. If you
  447. have an email address quote this in order to receive the instructions
  448. via email more quickly.
  449.  
  450. For users outside the UK the following methods of payment will be
  451. accepted:
  452.  
  453.    -  10 UK pounds money order or cheque.
  454.  
  455.    -  10 UK pounds in cash.
  456.  
  457.    -  The equivalent of 12 UK pounds in local currency. (At the time
  458.       of writing this is about 20 US dollars).
  459.  
  460.    -  A non-UK pounds cheque to the equivalent of 14 UK pounds. (At
  461.       the time of writing this is about 22 US dollars).
  462.  
  463. The additional charge for the last two payment methods is to cover
  464. currency exchange charges.
  465.  
  466. Members of CompuServe may register OPP electronically using the
  467. CompuServe SWREG facility. When logged on to CompuServe type GO SWREG
  468. and select the option to register shareware. When requested for the
  469. shareware ID use the value 6311 for OPP. The charge is $20 which will
  470. be added to your normal CompuServe account. When I receive
  471. notification from CompuServe of the registration I will email the
  472. registration details directly to you.
  473.  
  474. OPP may be freely distributed and uploaded to BBS's provided all
  475. files in the package are included.
  476.  
  477. For any further information I can be contacted via email:
  478.  
  479.     100661.2440@compuserve.com
  480.  
  481. For users with access to the WWW my home page contains the latest
  482. information about OPP, including an on-line version of this manual:
  483.  
  484.     http://ourworld.compuserve.com/homepages/andyc
  485.  
  486. Note that this software is provided as is, without any warranty of
  487. any kind. The author shall not be liable for any loss of data or
  488. damage arising from the use of this software.
  489.  
  490. 5. KEY FEATURES
  491.  
  492. OPP has the following key features:
  493.  
  494.    -  Available in two versions:
  495.            Version which runs on a Psion
  496.            Version which runs under MSDOS
  497.            
  498.    -  The MSDOS version of OPP may be run from an MSDOS prompt or
  499.       used with Psion's ODE environment.
  500.  
  501.    -  #define directive for simple macros, e.g.
  502.            #define MAX_ARRAY        10
  503.            
  504.    -  #define directive for macro functions, e.g.
  505.            #define FN(x)            3*x**2+2*x+1
  506.            
  507.    -  #undef to undefine macros
  508.    
  509.    -  Various built-in macros such as:
  510.            __LINE__, __FILE__, __DATE___, __TIME__, __PROC__, etc.
  511.            
  512.    -  ANSI # string producer supported in macro functions (although
  513.       the ! character is used rather than #).
  514.       
  515.    -  ANSI ## token pasting supported in macro functions (although
  516.       the !! characters are used rather than ##).
  517.       
  518.    -  Conditional translation directives: #if, #ifdef, #ifndef,
  519.       #else, #elif, #endif.
  520.       
  521.    -  Include files, both system and standard, e.g.
  522.            #include <os\calls>
  523.            #include "myprocs.oph"
  524.            
  525.    -  Supplied with lots of system include files (OS calls, etc.).
  526.    -  Line continuation character, e.g.
  527.            menu        "menu",            \
  528.                         "item1",%i        \
  529.                         "item2",%j
  530.                         
  531.    -  Multi-dimensional array support (standard OPL is limited to 1
  532.       dimensional arrays, OPP allows N-dimensional arrays).
  533.       
  534.    -  C style structures and pointers to structures, e.g.
  535.            STRUCT my_struct
  536.                 name$(10)
  537.                 value%
  538.                 next%
  539.            ENDS
  540.            PROC test
  541.                 local <my_struct*>p%
  542.                 p%=alloc(SIZEOF(my_struct))
  543.                 p%->name$        = "test"
  544.                 p%->value%       = 1
  545.                 p%->next%        = 0
  546.            ENDP
  547.            
  548.    -  A number of additional C style operators are supported, e.g.
  549.            i%++
  550.            i%--
  551.            i%+=2
  552.            i%-=2
  553.            i%*=2
  554.            i%/=2
  555.            
  556.    -  C style comments, e.g.
  557.            /* This is a comment */
  558.            global a% /* embedded comment */, b%
  559.            /* A multi-
  560.            line comment */
  561.            
  562.    -  Hooks for an OPL run-time debugger which is available
  563.       separately (see #pragma debug).
  564.       
  565.    -  Facility for creating library OPL source files containing
  566.       useful procedures which are only included in the resultant OPO module
  567.       if they are called.
  568.       
  569. -     Can check for calls to undefined procedures or procedures which
  570.       are never explicitly called.
  571.       
  572. -     Integrates with the Psion Program editor application and the
  573.       OPL translator.
  574.       
  575. -     Facility to abort translation at any point.
  576.  
  577. 6. MACROS
  578.  
  579. Macros are a convenient way of representing a sequence of commonly
  580. used characters with a symbolic name. Suppose for example there is a
  581. fixed size OPL array which has a size of 10. The size of the array
  582. may be referenced in a number of places throughout the OPL code and
  583. it is therefore useful to define a symbol or macro for the value 10.
  584. The symbolic name is then used throughout the code. This makes it
  585. more obvious what the value 10 represents in each particular case.
  586. Also, if ever the size of the array needs to be changed this only has
  587. to be done in one place rather than throughout the source code.
  588.  
  589. 6.1 Defining simple macros
  590. --------------------------
  591. The #define pre-processor directive is used to create a simple macro
  592. definition. For example the following line is added to the OPP source
  593. file:
  594.  
  595.         #define MAX_ARRAY      10
  596.         
  597. From this point onwards any occurrence of MAX_ARRAY in the OPP code
  598. will be replaced by 10 when the pre-processor is run.
  599.  
  600. The # character must be the first none-space character on the line;
  601. it may be proceeded by any number of space or tab characters. In
  602. general there may be any number of space or tab characters throughout
  603. the line provided that there is at least one between the define and
  604. the macro name, and the macro name and its value.
  605.  
  606. Macros may be defined from other macros, e.g.
  607.  
  608.         #define WIDTH          5
  609.         #define HEIGHT         10
  610.         #define SIZE           (WIDTH*HEIGHT)
  611.         
  612. In the above case when expanding the macro SIZE the value (5*10)
  613. would be substituted. The order is not important since macros are
  614. expanded when they are referenced rather than when they are defined,
  615. i.e. in theory the above could be written:
  616.  
  617.         #define SIZE          (WIDTH*HEIGHT)
  618.         #define WIDTH         5
  619.         #define HEIGHT        10
  620.         
  621. Note that macros which include operators are not automatically
  622. evaluated by OPP. Thus the macro SIZE is sent to the OPL translator
  623. as (5*10) not as 50. This can cause problems with the OPL translator.
  624. For example the following will not work:
  625.  
  626.         local array%(SIZE)
  627.         
  628. The problem is that the OPL translator also does not evaluate any
  629. expressions when the code is being translated and hence expects an
  630. integer for the array size, not an expression. You can work around
  631. this problem using a built in OPP function macro (see next section).
  632.  
  633. Following the ANSI standard, if a recursive macro is encountered it
  634. is not further expanded, e.g.
  635.  
  636.         #define ONE            (TWO-1)
  637.         #define TWO            (ONE+1)
  638.         
  639. This could lead to a recursive expansion, e.g. when expanding TWO it
  640. would lead to:
  641.  
  642.         TWO
  643.         (ONE+1)
  644.         ((TWO-1)+1)
  645.         (((ONE+1)-1)+1)
  646.         etc.
  647.         
  648. The ANSI standard states that the expansion will terminate at the
  649. value ((TWO-1)+1).
  650.  
  651. Although at first site the above recursive macro definition would
  652. appear to be pointless, it does have its uses, as demonstrated below:
  653.  
  654.         #define OPEN        PRINT "DEBUG MESSAGE:opening file" :OPEN
  655.         
  656. In the above case the following OPP code...
  657.  
  658.         OPEN "file.opd",a,a$,b$
  659.         
  660. ...would expand to...
  661.  
  662.         PRINT "DEBUG MESSAGE: opening file" :OPEN "file.opd",a,a$,b$
  663.         
  664. Note that the OPEN macro above could also be written more clearly as:
  665.  
  666.         #define OPEN                                               \
  667.                         PRINT "DEBUG MESSAGE:opening file"        :\
  668.                         OPEN
  669.                         
  670. A line continuation character is used in the above macro definition.
  671. If the "\" character is the very last character on a line OPP drops
  672. the "\" character and concatenates the line with the following line
  673. to produce one long line. Multiple spaces or tabs at the beginning of
  674. the line following the "\" are replaced with a single space or tab
  675. character. The total length of a line consisting of concatenated
  676. lines must not exceed 255 characters. The ":" character is required
  677. by the OPL translator in the above example to separate multiple
  678. statements on one line.
  679.  
  680. The line continuation character may be used in long or multi-
  681. statement macro definitions (as above) or in normal OPL code, e.g.
  682.  
  683.         dchoice "Choice", "Value1,\
  684.                            Value2,\
  685.                            Value3"
  686.                            
  687. 6.2 Defining function macros
  688. ----------------------------
  689. Macro functions are an extension of the simple macros described in
  690. the previous section. They are analogous to OPL procedures in that
  691. they take arguments. For example:
  692.  
  693.         #define GT?(a,b)        if (a<=b)                       :\
  694.                                         print a,">",b,"failed"  :\
  695.                                 endif
  696.                                 
  697. With the above definition the following OPP code....
  698.  
  699.         GT?(x%,0)
  700.         
  701. ...would expand to...
  702.  
  703.         if (x%<=0) :print x%,">",0,"failed" :endif
  704.         
  705. To define a macro function make sure that the "(" follows immediately
  706. after the macro function name. This is followed by a comma separated
  707. list of function variables terminated by a ")". A macro function may
  708. have any number of arguments between 0 and 20 inclusive.
  709.  
  710. Each occurrence of a function argument within the macro definition is
  711. replaced by the associated value when the macro is expanded.
  712.  
  713. Like simple macros, a macro function definition may include other
  714. macros, for example:
  715.  
  716.         #define AX                     axreg%
  717.         #define OSFLAGS                osflags%
  718.         #define OSFN(fn)               OSFLAGS=os(fn,addr(AX))
  719.         #define OSSUB(fn,sub)          AX=sub :OSFN(fn)
  720.         
  721. Using some of the above macros the following code demonstrates how to
  722. access an OS call in the Psion ROM using a macro function (the full
  723. macro definitions appear in the supplied include files OS\call.oph
  724. and os\gen.oph):
  725.  
  726.         #include <os\gen>
  727.         #include <os\call>
  728.         PROC main:
  729.                 local OSREGS
  730.                 OSSUB(GenManager,GenGetRamSizeInParas)
  731.                 print -(AX/64);"K RAM"
  732.                 get
  733.         ENDP
  734.         
  735. There is a built in macro function called OPPEVAL() which takes one
  736. argument. When pre-processing a file the argument is evaluated by
  737. OPP, for example, going back to the example in the previous section:
  738.  
  739.         #define WIDTH          5
  740.         #define HEIGHT         10
  741.         #define SIZE           (WIDTH*HEIGHT)
  742.         local array%(OPPEVAL(SIZE))
  743.         
  744. The OPPEVAL() function is required in order to evaluate (5*10) since
  745. otherwise OPP would pass the line as follows to the OPL translator:
  746.  
  747.         local array%((5*10))
  748.         
  749. This would fail since the OPL translator can only handle simple
  750. numbers in an array dimension.
  751.  
  752. The OPPEVAL() macro may also be used to evaluate an expression at
  753. translation time rather than at run time for performance and space
  754. reasons, for example:
  755.  
  756.         #define FLAGMASK       OPPEVAL(FLAG1 OR FLAG2 OR FLAG3)
  757.         
  758. If the OPPEVAL() function was not present in the above definition
  759. then for every occurrence of FLAGMASK within the OPL source a
  760. calculation would be required at run time.
  761.  
  762. 6.3 Notes on macro expansion
  763. ----------------------------
  764. When pre-processing a line OPP looks for macro symbols delimited by
  765. certain characters. The complete set of characters is:
  766.  
  767. (          ,        -         <        :         SPACE
  768. )          =        *         >        |         TAB
  769. ;          +        /         #        !         START/END OF LINE
  770. .                      
  771.                           
  772. The same delimiters are also used when OPP looks for argument
  773. variables within a macro function definition.
  774.  
  775. When the pre-processor encounters any strings they are copied
  776. directly without pre-processing.
  777.  
  778. Take the following macro definition...
  779.  
  780.         #define TEST        1
  781.         
  782. ...then the following examples demonstrate what will and will not be
  783. expanded:
  784.  
  785.         print (TEST+1)   TEST expanded
  786.         print (Test+1)   Test not expanded - macros are case sensitive
  787.         print (TEST%+1)  TEST not expanded since % is not a delimiter
  788.         print "TEST"     TEST not expanded - any strings are not
  789.                  pre-processed
  790.  
  791. 6.4 Undefining macros
  792. ---------------------
  793. A macro definition may be removed using the #undef directive followed
  794. by the macro name, for example:
  795.  
  796.         #define DEBUG
  797.         #define MOD(a,b)       (a-(a/b)*b)
  798.         #undef DEBUG
  799.         #undef MOD
  800.         
  801. 6.5 Built-in macros
  802. -------------------
  803. OPP includes a number of pre-defined built-in macros:
  804.  
  805.    Macro                  Purpose                  Example of value
  806. __FILE__     Name of file being translated      "LOC::M:\OPP\TEST.OPP"
  807. __LINE__     Line number being translated       23
  808. __DATE__     Date of translation                "May 10 1995"
  809. __TIME__     Time of translation                "23:53:06"
  810. __PROC__     Name of current procedure          "main"
  811. OPP          OPP version number                 $16F
  812. Psion*       Indicates translating on a Psion   
  813. DOS          Indicates translating on a PC      
  814. XTran*       Set if translating for S3 on a     
  815.              S3a
  816. OsVersion*   Psion OS version number, 3.18F=    $318F
  817. RomVersion*  Psion ROM version number, 3.20F=   $320F
  818. PsuType*     Power supply type 0=old MC,        3
  819.              1=MC, 2=Series 3, 3=Series 3a
  820. LcdType*     LCD type, 11=S3a                   11
  821. OPPEVAL()    Evaluate expression                OPPEVAL(SIZE+2)
  822. SIZEOF()     See section on structures          SIZEOF(my_struct)
  823. OFFSETOF()   See section on structures          OFFSETOF(my_struct,field)
  824.  
  825. *These macros are not available when using the MSDOS version of OPP.
  826.  
  827. 6.6 ! special character
  828. -----------------------
  829. The ANSI standard defines the # character to have a special meaning
  830. within a macro definition. Due to the fact that # is used within OPL,
  831. OPP looks for the character ! rather than #. Consider:
  832.  
  833.         #define ASSERT(expr)    if not (expr)            :\
  834.                                         print !expr,"failed"    :\
  835.                                 endif
  836.                                 
  837. The presence of the ! character before the macro function variable
  838. instructs OPP to quote the expression when expanded. Thus the
  839. following line...
  840.  
  841.         ASSERT(a%>0)
  842.         
  843. ...would expand to...
  844.  
  845.         if not (a%>0) :print "a%>0","failed" :endif
  846.         
  847. This mechanism is required since simply adding quotes around the
  848. variable would cause OPP to copy the string directly, i.e. if the
  849. definition was...
  850.  
  851.         #define ASSERT(expr)    if not (expr)            :\
  852.                                         print "expr","failed"    :\
  853.                                 endif
  854.                                 
  855. ...then the above line would expand to...
  856.  
  857.         if not (a%>0) :print "expr","failed" :endif
  858.         
  859. 6.7 !! special characters
  860. -------------------------
  861. ## is another ANSI standard token. Again, due to the use of # by OPL,
  862. the pre-processor uses the identifiers !! instead. Consider the
  863. following macro definition:
  864.  
  865.         #define M(name)        module!!name!!%:
  866.         
  867. The !! characters indicate a delimiter for a macro function argument.
  868. OPP notes the delimiter and then discards the !! characters from the
  869. expansion. Thus the following...
  870.  
  871.         M(a)
  872.         
  873. ...would expand to...
  874.  
  875.         modulea%:
  876.         
  877. Without the !! OPP would not detect the presence of the name argument
  878. since neither "e" nor % are normal delimiter characters.
  879.  
  880. 7. CONDITIONS
  881.  
  882. OPL includes the conditions if, else, elseif and endif. OPP has
  883. similar directives #if, #ifdef, #ifndef, #else, #elif and #endif
  884. which are analogous to OPL commands.
  885.  
  886. Using conditional pre-processor directives provides control over the
  887. sections of OPP code which are to be translated. For example:
  888.  
  889.         #define DEBUG
  890.         #ifdef DEBUG
  891.                 print "Translated with brief debug enabled"
  892.                 #ifdef MOREDEBUG
  893.                         print "Translated with additional debug enabled"
  894.                 #endif
  895.         #else
  896.                 print "Debug code not translated"
  897.         #endif
  898.         
  899. The #ifdef directive tests for the presence of a macro, if it exists
  900. then the remaining code up to a matching #endif or #else is passed to
  901. the OPL translator. #ifndef has the opposite affect, i.e. the
  902. condition is true if the macro does not exist.
  903.  
  904. The condition "#if expression" is true if the expression evaluates to
  905. true or non-zero. Examples of valid expressions are as follows:
  906.  
  907.         #if DEBUG_LEVEL > 2
  908.         #if OsVersion >= $300
  909.         #if LcdType = 11
  910.         #if (PsuType = 2) or (PsuType = 3)
  911.  
  912. The "#elif expression" may be used as follows:
  913.  
  914.         #if DEBUG_LEVEL = 1
  915.                 print "debug level 1"
  916.         #elif DEBUG_LEVEL = 2
  917.                 print "debug level 2"
  918.         #elif DEBUG_LEVEL = 3
  919.                 print "debug level 3"
  920.         #else
  921.                 print "no debug"
  922.         #endif
  923.  
  924. Note that the current release of OPP does not support use of
  925. "defined()" in #if or #elif expressions.
  926.